package com.ljkj.blockpay.util;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by yp on 2022/3/10
 */
public class JsonUtil {
    /**
     * Null serialize is used because else Gson will ignore all null fields.
     */
    private static Gson gson = new GsonBuilder().serializeNulls().create();

    /**
     * Made private because all methods are static and hence do not need
     * object instantiation
     */
    private JsonUtil() {
    }

    /**
     * To Json Converter using Goolge's Gson Package
     * <p/>
     * this method converts a simple object to a json string
     *
     * @param obj
     * @return a json string
     */
    public static <T> String toJsonObj(T obj) {
        return gson.toJson(obj);
    }

    /**
     * Converts a collection of objects using Google's Gson Package
     *
     * @param objCol
     * @return a json string array
     */
    public static <T> String toJsonList(List<T> objCol) {
        return gson.toJson(objCol);
    }

    /**
     * Returns the specific object given the Json String
     *
     * @param <T>
     * @param jsonString
     * @param obj
     * @return a specific object as defined by the user calling the method
     */
    public static <T> T jsonToObj(String jsonString, Class<T> obj) {
        return gson.fromJson(jsonString, obj);
    }


    public static <K, V> String toJsonMap(Map<K, V> map) {
        return gson.toJson(map);
    }

    public static <K, V> Map<K, V> jsonToMap(String jsonMap, Type type) {
        return gson.fromJson(jsonMap, type);
    }

    /**
     * Returns a list of specified object from the given json array
     *
     * @param t the type defined by the user
     * @return a list of specified objects as given in the json array
     * e.g.
     * <pre>
     * Type collectionType = new TypeToken<List<Person>>(){}.getType();<br/>
     * List<Person>personList =  JsonUtil.fromJsonToList(jsonStr,collectionType);
     * </pre>
     */
    public static <T> List<T> jsonToList(String jsonString, Type t) {
        return gson.fromJson(jsonString, t);
    }

    public static <T> ArrayList<T> jsonToArrayList(String jsonString, Type t) {
        return gson.fromJson(jsonString, t);
    }

    public static <T> LinkedList<T> jsonToLinkedList(String json, Class<T> clazz) {
        Type type = new TypeToken<LinkedList<JsonObject>>() {
        }.getType();
        LinkedList<JsonObject> jsonObjects = new Gson().fromJson(json, type);

        LinkedList<T> linkedList = new LinkedList<>();
        for (JsonObject jsonObject : jsonObjects) {
            linkedList.add(new Gson().fromJson(jsonObject, clazz));
        }
        return linkedList;
    }
}
